/**
 * 
 */
package org.mips.Sirius.provider.SIRI;

import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import org.mips.Sirius.components.StopMonitoring;
import org.mips.Sirius.components.StopPoint;
import org.mips.Sirius.components.TimeMonitoring;
import org.mips.Sirius.components.Vehicle;
import org.mips.Sirius.provider.ProviderException;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Log;

/**
 * 
 * @author Alessandro
 * 
 */
public class SIRIStopMonitoringDelivery {

	ArrayList<StopPoint> monitoredStopPoints;
	StopMonitoring monitoring;
	static XmlPullParserFactory factory;

	static {
		try {
			factory = XmlPullParserFactory.newInstance();
		} catch (XmlPullParserException e) {
			Log.d("tap", "Couldn't get XmlPullParser instance");
		}
	}

	public SIRIStopMonitoringDelivery(String xml) throws ProviderException {
		parse(xml);
	}

	private void parse(String xml) throws ProviderException {

		monitoredStopPoints = new ArrayList<StopPoint>();
		monitoring = new StopMonitoring();
		ArrayList<Vehicle> monitoredVehicles = new ArrayList<Vehicle>();
		Vehicle monitoredVehicle = null;
		TimeMonitoring timeMonitoring = null;
		ArrayList<String> viaNames = null;

		try {
			factory.setNamespaceAware(true);
			XmlPullParser xpp = factory.newPullParser();
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

			xpp.setInput(new StringReader(xml));
			int eventType = xpp.getEventType();

			String stopRef = null;
			int latitude = 0, longitude = 0;

			boolean openVehicleLocationAtStop = false;
			boolean openMonitoringRef = false;
			boolean openLongitude = false;
			boolean openLatitude = false;
			boolean openLineRef = false;
			boolean openAimed = false;
			boolean openExpected = false;
			boolean openAimedDep = false;
			boolean openExpectedDep = false;
			boolean openPlace = false;
			boolean openOrigin = false;
			boolean openDestination = false;

			while (eventType != XmlPullParser.END_DOCUMENT) {
				if (eventType == XmlPullParser.START_TAG) {
					if (xpp.getName().equals("Longitude")) {
						openLongitude = true;
					} else if (xpp.getName().equals("Latitude")) {
						openLatitude = true;
					} else if (xpp.getName().equals("MonitoringRef")) {
						openMonitoringRef = true;
					} else if (xpp.getName().equals("VehicleLocationAtStop")) {
						openVehicleLocationAtStop = true;
					} else if (xpp.getName().equals("MonitoredVehicleJourney")) {
						monitoredVehicle = new Vehicle("", "");
						viaNames = new ArrayList<String>();
					} else if (xpp.getName().equals("LineRef")) {
						openLineRef = true;
					} else if (xpp.getName().equals("MonitoredCall")) {
						timeMonitoring = new TimeMonitoring();
					} else if (xpp.getName().equals("AimedArrivalTime")) {
						openAimed = true;
					} else if (xpp.getName().equals("ExpectedArrivalTime")) {
						openExpected = true;
					} else if (xpp.getName().equals("AimedDepartureTime")) {
						openAimedDep = true;
					} else if (xpp.getName().equals("ExpectedDepartureTime")) {
						openExpectedDep = true;
					} else if (xpp.getName().equals("PlaceName")) {
						openPlace = true;
					} else if (xpp.getName().equals("OriginName")) {
						openOrigin = true;
					} else if (xpp.getName().equals("DestinationName")) {
						openDestination = true;
					}
				} else if (eventType == XmlPullParser.END_TAG) {
					if (xpp.getName().equals("MonitoredStopVisit")) {
						monitoredStopPoints.add(new StopPoint(stopRef, "",
								latitude, longitude));
					} else if (xpp.getName().equals("Longitude")) {
						openLongitude = false;
					} else if (xpp.getName().equals("Latitude")) {
						openLatitude = false;
					} else if (xpp.getName().equals("MonitoringRef")) {
						openMonitoringRef = false;
					} else if (xpp.getName().equals("VehicleLocationAtStop")) {
						openVehicleLocationAtStop = false;
					} else if (xpp.getName().equals("MonitoredVehicleJourney")) {
						monitoredVehicle.setViaNames(viaNames);
						monitoredVehicles.add(monitoredVehicle);
					} else if (xpp.getName().equals("StopMonitoringDelivery")) {
						monitoring.setLastMonitoredVehicles(monitoredVehicles);
					} else if (xpp.getName().equals("LineRef")) {
						openLineRef = false;
					} else if (xpp.getName().equals("MonitoredCall")) {
						monitoredVehicle.setTimes(timeMonitoring);
					} else if (xpp.getName().equals("AimedArrivalTime")) {
						openAimed = false;
					} else if (xpp.getName().equals("ExpectedArrivalTime")) {
						openExpected = false;
					} else if (xpp.getName().equals("AimedDepartureTime")) {
						openAimedDep = false;
					} else if (xpp.getName().equals("ExpectedDepartureTime")) {
						openExpectedDep = false;
					} else if (xpp.getName().equals("PlaceName")) {
						openPlace = false;
					} else if (xpp.getName().equals("OriginName")) {
						openOrigin = false;
					} else if (xpp.getName().equals("DestinationName")) {
						openDestination = false;
					}

				} else if (eventType == XmlPullParser.TEXT) {
					if (openLatitude && openVehicleLocationAtStop) {
						latitude = Integer.valueOf(xpp.getText());
					} else if (openLongitude && openVehicleLocationAtStop) {
						longitude = Integer.valueOf(xpp.getText());
					} else if (openMonitoringRef) {
						stopRef = xpp.getText();
					} else if (openLineRef) {
						monitoredVehicle.setLineReference(xpp.getText());
					} else if (openAimed || openExpected || openAimedDep
							|| openExpectedDep) {
						Date date = df.parse(xpp.getText());
						if (openAimed) {
							timeMonitoring.setAimedArrivalTime(date);
						} else if (openExpected) {
							timeMonitoring.setExpectedArrivalTime(date);
						} else if (openAimedDep) {
							timeMonitoring.setAimedDepartureTime(date);
						} else if (openExpectedDep) {
							timeMonitoring.setExpectedDepartureTime(date);
						}
					} else if (openPlace) {
						viaNames.add(xpp.getText());
					} else if (openOrigin) {
						monitoredVehicle.setOriginName(xpp.getText());
					} else if (openDestination) {
						monitoredVehicle.setDestinationName(xpp.getText());
					}
				}
				eventType = xpp.next();
			}
		} catch (Exception e) {
			throw new ProviderException(e,
					"Couldn't parse StopMonitoringDelivery");
		}

		/*
		 * Log.d("debug", "Found " + monitoredStopPoints.size() +
		 * " monitored stops: " + monitoredStopPoints); Log.d("tap", "Found " +
		 * monitoring);
		 */
	}

	public ArrayList<StopPoint> getStopPoints() {
		return monitoredStopPoints;
	}

	public StopMonitoring getStopMonitoring() {
		return monitoring;
	}
}
